package com.lineage.server.model.Instance;

import com.lineage.server.model.L1AttackPc;
import com.lineage.server.model.L1CastleLocation;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1Clan;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.L1War;
import com.lineage.server.model.L1WarSpawn;
import com.lineage.server.serverpackets.S_DoActionGFX;
import com.lineage.server.serverpackets.S_NPCPack;
import com.lineage.server.serverpackets.S_RemoveObject;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Npc;
import com.lineage.server.thread.GeneralThreadPool;
import com.lineage.server.timecontroller.server.ServerWarExecutor;
import com.lineage.server.types.Point;
import com.lineage.server.world.World;
import com.lineage.server.world.WorldClan;
import com.lineage.server.world.WorldNpc;
import com.lineage.server.world.WorldWar;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1TowerInstance extends L1NpcInstance {
  private static final long serialVersionUID = 1L;
  
  private static final Log _log = LogFactory.getLog(L1TowerInstance.class);
  
  private int _castle_id;
  
  private int _crackStatus;
  
  public L1TowerInstance(L1Npc template) {
    super(template);
  }
  
  public void onPerceive(L1PcInstance perceivedFrom) {
    try {
      perceivedFrom.addKnownObject((L1Object)this);
      perceivedFrom.sendPackets((ServerBasePacket)new S_NPCPack(this));
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void onAction(L1PcInstance player) {
    try {
      if (getCurrentHp() > 0 && !isDead()) {
        L1AttackPc l1AttackPc = new L1AttackPc(player, this);
        if (l1AttackPc.calcHit())
          l1AttackPc.calcDamage(); 
        l1AttackPc.action();
        l1AttackPc.commit();
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void receiveDamage(L1Character attacker, int damage) {
    boolean isDamage = false;
    if (this._castle_id == 0)
      if (isSubTower()) {
        this._castle_id = 7;
      } else {
        this._castle_id = L1CastleLocation.getCastleId(getX(), getY(), getMapId());
      }  
    if (this._castle_id > 0 && ServerWarExecutor.get().isNowWar(this._castle_id)) {
      if (this._castle_id == 7 && !isSubTower()) {
        int subTowerDeadCount = 0;
        Iterator<L1NpcInstance> iterator = WorldNpc.get().all().iterator();
        while (iterator.hasNext()) {
          L1NpcInstance npc = iterator.next();
          if (npc instanceof L1TowerInstance) {
            L1TowerInstance tower = (L1TowerInstance)npc;
            if (!tower.isSubTower() || !tower.isDead())
              continue; 
            subTowerDeadCount++;
          } 
        } 
      } 
      isDamage = true;
    } 
    if (isDamage) {
      L1PcInstance pc = null;
      if (attacker instanceof L1PcInstance) {
        pc = (L1PcInstance)attacker;
      } else if (attacker instanceof L1PetInstance) {
        pc = (L1PcInstance)((L1PetInstance)attacker).getMaster();
      } else if (attacker instanceof L1SummonInstance) {
        pc = (L1PcInstance)((L1SummonInstance)attacker).getMaster();
      } else if (attacker instanceof L1IllusoryInstance) {
        pc = (L1PcInstance)((L1IllusoryInstance)attacker).getMaster();
      } else {
        boolean bool = attacker instanceof L1EffectInstance;
      } 
      if (pc == null)
        return; 
      boolean existDefenseClan = false;
      Collection<L1Clan> allClans = WorldClan.get().getAllClans();
      Iterator<L1Clan> iter = allClans.iterator();
      while (iter.hasNext()) {
        L1Clan clan = iter.next();
        int clanCastleId = clan.getCastleId();
        if (clanCastleId == this._castle_id) {
          existDefenseClan = true;
          break;
        } 
      } 
      boolean isProclamation = false;
      Iterator<L1War> iterator2 = WorldWar.get().getWarList().iterator();
      while (iterator2.hasNext()) {
        L1War war = iterator2.next();
        if (this._castle_id == war.getCastleId()) {
          isProclamation = war.checkClanInWar(pc.getClanname());
          break;
        } 
      } 
      if (existDefenseClan && !isProclamation)
        return; 
      if (getCurrentHp() > 0 && !isDead()) {
        int newHp = getCurrentHp() - damage;
        if (newHp <= 0 && !isDead()) {
          setCurrentHpDirect(0);
          setDead(true);
          setStatus(36);
          this._crackStatus = 0;
          Death death = new Death(this, attacker);
          GeneralThreadPool.get().execute(death);
        } 
        if (newHp > 0) {
          setCurrentHp(newHp);
          if (getMaxHp() * 1 / 4 > getCurrentHp()) {
            if (this._crackStatus != 4) {
              broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 35));
              setStatus(35);
              this._crackStatus = 4;
            } 
          } else if (getMaxHp() * 2 / 4 > getCurrentHp()) {
            if (this._crackStatus != 3) {
              broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 34));
              setStatus(34);
              this._crackStatus = 3;
            } 
          } else if (getMaxHp() * 3 / 4 > getCurrentHp()) {
            if (this._crackStatus != 2) {
              broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 33));
              setStatus(33);
              this._crackStatus = 2;
            } 
          } else if (getMaxHp() >= getCurrentHp() && this._crackStatus != 1) {
            broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 32));
            setStatus(32);
            this._crackStatus = 1;
          } 
        } 
      } else if (!isDead()) {
        setDead(true);
        setStatus(36);
        Death death2 = new Death(this, attacker);
        GeneralThreadPool.get().execute(death2);
      } 
    } 
  }
  
  public void setCurrentHp(int i) {
    int currentHp = Math.min(i, getMaxHp());
    if (getCurrentHp() == currentHp)
      return; 
    setCurrentHpDirect(currentHp);
  }
  
  public void deleteMe() {
    this._destroyed = true;
    if (getInventory() != null)
      getInventory().clearItems(); 
    allTargetClear();
    this._master = null;
    World.get().removeVisibleObject((L1Object)this);
    World.get().removeObject((L1Object)this);
    Iterator<L1PcInstance> iterator = World.get().getRecognizePlayer((L1Object)this).iterator();
    while (iterator.hasNext()) {
      L1PcInstance pc = iterator.next();
      pc.removeKnownObject((L1Object)this);
      pc.sendPackets((ServerBasePacket)new S_RemoveObject((L1Object)this));
    } 
    removeAllKnownObjects();
  }
  
  public boolean isSubTower() {
    return !(getNpcTemplate().get_npcId() != 81190 && getNpcTemplate().get_npcId() != 81191 && 
      getNpcTemplate().get_npcId() != 81192 && getNpcTemplate().get_npcId() != 81193);
  }
  
  private class Death implements Runnable {
    private final L1Character _lastattacker;
    
    private L1TowerInstance _tower;
    
    public Death(L1TowerInstance tower, L1Character attacker) {
      this._tower = null;
      this._lastattacker = attacker;
      this._tower = tower;
    }
    
    public void run() {
      this._tower.setCurrentHpDirect(0);
      this._tower.setDead(true);
      this._tower.setStatus(36);
      this._tower.getMap().setPassable((Point)this._tower.getLocation(), true);
      this._tower.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(this._tower.getId(), 36));
      if (!this._tower.isSubTower()) {
        L1WarSpawn warspawn = new L1WarSpawn();
        warspawn.SpawnCrown(this._tower._castle_id);
      } 
    }
  }
}
